package com.yanqu.xiuxian.crosssystem.manger.elementalbonds.logic;

import com.yanqu.xiuxian.config.elementalbonds.ElementalBondsCardConfig;
import com.yanqu.xiuxian.config.elementalbonds.ElementalBondsConfigMgr;
import com.yanqu.xiuxian.config.elementalbonds.enums.*;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsCardData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsGameData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsPlayerData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.data.ElementalBondsRoomData;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.entity.*;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.enums.ElementalBondsCardType;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.param.ElementalBondsCardParam;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.param.ElementalBondsMoveParam;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.param.ElementalBondsSkillParam;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.result.ElementalBondsOperateResult;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.result.ElementalBondsOperateRoundResult;
import com.yanqu.xiuxian.crosssystem.manger.elementalbonds.result.ElementalBondsOperateStageResult;
import com.yanqu.xiuxian.server.protocol.GameErrorCode;

import java.util.*;

public class ElementalBondsCardLogic {

    public static ElementalBondsOperateResult operate( ElementalBondsRoomData elementalBondsRoomData, boolean isPlayer1,
                                                      ElementalBondsCardParam elementalBondsCardParam, int guideDropNo, int roomRound) {
        ElementalBondsPlayerData elementalBondsPlayerData = isPlayer1 ? elementalBondsRoomData.getPlayer1() : elementalBondsRoomData.getPlayer2();
        ElementalBondsGameData elementalBondsGameData = elementalBondsRoomData.getGameData().clone();
        boolean stepMax = ElementalBondsGameLogic.isStepMax(elementalBondsRoomData.getModeId(), elementalBondsPlayerData);
        ElementalBondsOperateResult elementalBondsOperateResult = new ElementalBondsOperateResult(ElementalBondsOperateType.USE_CARD, stepMax, elementalBondsRoomData.getTurnPlayer());
        elementalBondsOperateResult.setSkillId(elementalBondsCardParam.getCardId());
        ElementalBondsCardConfig elementalBondsCardConfig = ElementalBondsConfigMgr.getInstance().getCardConfigMap().get(elementalBondsCardParam.getCardId());
        // 检查配置
        if (elementalBondsCardConfig == null) {
            elementalBondsOperateResult.setRet(GameErrorCode.E_ELEMENTAL_BONDS_CARD_CONFIG_NO_EXIST);
            return elementalBondsOperateResult;
        }
        // 检查卡片
        elementalBondsOperateResult.setRet(check(elementalBondsGameData, elementalBondsPlayerData, elementalBondsCardParam));
        if (elementalBondsOperateResult.getRet() != GameErrorCode.E_SUCCESS_VALUE) {
            return elementalBondsOperateResult;
        }
        // 使用卡片
        Random random = new Random();
        use(elementalBondsCardConfig, elementalBondsCardParam, elementalBondsGameData, elementalBondsOperateResult, elementalBondsPlayerData,
                random, guideDropNo, roomRound, elementalBondsRoomData.getTurnPlayer());
        if (elementalBondsOperateResult.getRet() != GameErrorCode.E_SUCCESS_VALUE) {
            return elementalBondsOperateResult;
        }
        ElementalBondsSceneLogic.operateEnd(random, elementalBondsGameData, elementalBondsOperateResult);
        elementalBondsOperateResult.setElementalBondsGameData(elementalBondsGameData);
        return elementalBondsOperateResult;
    }

    private static int check(ElementalBondsGameData elementalBondsGameData, ElementalBondsPlayerData elementalBondsPlayerData, ElementalBondsCardParam elementalBondsCardParam) {
        ElementalBondsCardData elementalBondsCardData = elementalBondsPlayerData.getElementalBondsCardData();
        if (elementalBondsCardData.getCardId() != elementalBondsCardParam.getCardId()) {
            return GameErrorCode.E_ELEMENTAL_BONDS_CARD_NO_EXIST;
        }
        if (elementalBondsCardData.getCardMp() < elementalBondsCardData.getCardMaxMp()) {
            return GameErrorCode.E_ELEMENTAL_BONDS_CARD_MP_NO_FULL;
        }
        // 判断方块存不存在(不需要方块的都是0,0，也是存在的)
        if (!ElementalBondsBlockLogic.exist(elementalBondsGameData.getBlockList(), elementalBondsCardParam)) {
            return GameErrorCode.E_ELEMENTAL_BONDS_POS_NO_EXIST;
        }
        ElementalBondsCardType elementalBondsCardType = ElementalBondsCardType.forType(elementalBondsCardParam.getCardId());
        return elementalBondsCardType.check(elementalBondsGameData, elementalBondsCardParam);
    }

    public static int check_23(ElementalBondsGameData elementalBondsGameData, ElementalBondsSkillParam elementalBondsSkillParam) {
        List<List<ElementalBondsBlock>> blockList = elementalBondsGameData.getBlockList();
        if (!ElementalBondsBlockLogic.exist(blockList, elementalBondsSkillParam.getFromX(), elementalBondsSkillParam.getFromY())) {
            return GameErrorCode.E_ELEMENTAL_BONDS_POS_NO_EXIST;
        }
        ElementalBondsBlock elementalBondsBlock = blockList.get(elementalBondsSkillParam.getFromY()).get(elementalBondsSkillParam.getFromX());
        if (elementalBondsBlock.getElementalBondsBlockType() == ElementalBondsBlockType.SMART_BOX) {
            return GameErrorCode.E_ELEMENTAL_BONDS_BLOCK_CAN_NOT_CHOOSE;
        }
        return GameErrorCode.E_SUCCESS_VALUE;
    }

    private static void use(ElementalBondsCardConfig elementalBondsCardConfig, ElementalBondsCardParam elementalBondsCardParam,
                            ElementalBondsGameData elementalBondsGameData, ElementalBondsOperateResult elementalBondsOperateResult, ElementalBondsPlayerData elementalBondsPlayerData,
                            Random random, int guideDropNo, int roomRound, int turnPlayer) {
        // 使用卡片
        ElementalBondsCardType elementalBondsCardType = ElementalBondsCardType.forType(elementalBondsCardParam.getCardId());
        Set<ElementalBondsBlock> elementalBondsBlockSet = elementalBondsCardType.use(elementalBondsCardConfig, elementalBondsCardParam,
                elementalBondsGameData, elementalBondsOperateResult, elementalBondsPlayerData, random, guideDropNo > 0, roomRound, turnPlayer, true);
        elementalBondsPlayerData.getElementalBondsCardData().addTurnUseTimes();
        // 消除
        ElementalBondsMoveParam elementalBondsMoveParam = null;
        if (!(elementalBondsCardParam.getFromX() == 0 && elementalBondsCardParam.getFromY() == 0 && elementalBondsCardParam.getToX() == 0 && elementalBondsCardParam.getToY() == 0)) {
            elementalBondsMoveParam = new ElementalBondsMoveParam(elementalBondsCardParam);
        }
        ElementalBondsEliminateLogic.bigEliminate(elementalBondsGameData, elementalBondsPlayerData, elementalBondsMoveParam,
                elementalBondsBlockSet, elementalBondsOperateResult, random, guideDropNo, roomRound, turnPlayer);
        // 卡片结束效果
        elementalBondsOperateResult.addElementalBondsOperateEffect(new ElementalBondsOperateEffect(ElementalBondsEffectType.SKILL_END));
    }

    public static void card_13_move(ElementalBondsGameData elementalBondsGameData, ElementalBondsPlayerData elementalBondsPlayerData,
                                    ElementalBondsOperateType elementalBondsOperateType, Set<ElementalBondsBlock> elementalBondsBlockSet,
                                    List<ElementalBondsBomb> elementalBondsBombList) {
        ElementalBondsCardData elementalBondsCardData = elementalBondsPlayerData.getElementalBondsCardData();
        if (elementalBondsCardData.getCardId() != ElementalBondsCardType.CARD_13.getType() || elementalBondsCardData.getTurnUseTimes() <= 0) {
            return;
        }
        if (elementalBondsOperateType != ElementalBondsOperateType.MOVE || elementalBondsBlockSet.isEmpty()) {
            return;
        }
        for (List<ElementalBondsBlock> elementalBondsBlocks : elementalBondsGameData.getBlockList()) {
            for (ElementalBondsBlock elementalBondsBlock : elementalBondsBlocks) {
                if (!elementalBondsBlockSet.contains(elementalBondsBlock)
                        && elementalBondsBlock.getElementalBondsBlockEffectList().stream().anyMatch(
                        elementalBondsBlockEffect -> elementalBondsBlockEffect.getEffectType() == ElementalBondsBlockEffectType.SKILL_13)) {
                    elementalBondsBlockSet.add(elementalBondsBlock);
                }
            }
        }
        ElementalBondsBombLogic.fastBoom(elementalBondsGameData, elementalBondsOperateType, elementalBondsBlockSet, elementalBondsBombList);
    }

    public static void card_13_moveEnd(ElementalBondsGameData elementalBondsGameData, ElementalBondsPlayerData elementalBondsPlayerData,
                                       ElementalBondsOperateResult elementalBondsOperateResult, ElementalBondsOperateType elementalBondsOperateType, Random random) {
        ElementalBondsCardData elementalBondsCardData = elementalBondsPlayerData.getElementalBondsCardData();
        if (elementalBondsOperateType != ElementalBondsOperateType.MOVE || elementalBondsCardData.getTurnUseTimes() <= 0) {
            return;
        }

        int addStep = elementalBondsOperateResult.getBombAddStepStatus() == 1 ? 1 : 0;
        for (ElementalBondsOperateShow elementalBondsOperateShow : elementalBondsOperateResult.getElementalBondsOperateShowList()) {
            for (ElementalBondsOperateRoundResult elementalBondsOperateRoundResult : elementalBondsOperateShow.getElementalBondsOperateRoundResultList()) {
                for (ElementalBondsOperateStageResult elementalBondsOperateStageResult : elementalBondsOperateRoundResult.getStageResultList()) {
                    for (ElementalBondsBlock elementalBondsBlock : elementalBondsOperateStageResult.getAddStepBlockList()) {
                        if (elementalBondsBlock.getElementalBondsBlockType() == ElementalBondsBlockType.DIAN_SHAN_LEI_MING) {
                            addStep += ElementalBondsSceneLogic.scene_09_getAddStepNum();
                        }
                    }
                }
            }
        }
        if (elementalBondsPlayerData.getStep() <= 1 && addStep < 1) {
            return;
        }
        ElementalBondsCardType elementalBondsCardType = ElementalBondsCardType.CARD_13;
        ElementalBondsCardConfig elementalBondsCardConfig = ElementalBondsConfigMgr.getInstance().getCardConfigMap().get(elementalBondsCardType.getType());
        if (elementalBondsCardConfig != null) {
            elementalBondsCardType.use(elementalBondsCardConfig, null, elementalBondsGameData,
                    elementalBondsOperateResult, elementalBondsPlayerData, random, false, 0, 0, false);
        }
    }

    public static void card_22_eliminateEnd(ElementalBondsGameData elementalBondsGameData, ElementalBondsPlayerData elementalBondsPlayerData,
                                            ElementalBondsOperateResult elementalBondsOperateResult, ElementalBondsOperateType elementalBondsOperateType, Random random) {
        if (elementalBondsOperateType == ElementalBondsOperateType.MOVE && elementalBondsPlayerData.getStep() <= 1 && elementalBondsOperateResult.getBombAddStepStatus() != 1) {
            return; // 本次移动结束后步数就为0 && 没有加步数
        }

        // 找最后一次消除的数据
        List<ElementalBondsOperateRoundResult> elementalBondsOperateRoundResultList = new ArrayList<>();
        List<ElementalBondsOperateShow> elementalBondsOperateShowList = elementalBondsOperateResult.getElementalBondsOperateShowList();
        for (int i = elementalBondsOperateShowList.size() - 1; i >= 0; i--) {
            ElementalBondsOperateShow elementalBondsOperateShow = elementalBondsOperateShowList.get(i);
            if (!elementalBondsOperateShow.getElementalBondsOperateRoundResultList().isEmpty()) {
                elementalBondsOperateRoundResultList = elementalBondsOperateShow.getElementalBondsOperateRoundResultList();
                break;
            }
        }

        // 第一次使用掉的小恶魔方块
        List<ElementalBondsBlock> useElementalBondsBlockList = new ArrayList<>();
        for (ElementalBondsOperateRoundResult elementalBondsOperateRoundResult : elementalBondsOperateRoundResultList) {
            for (ElementalBondsOperateStageResult elementalBondsOperateStageResult : elementalBondsOperateRoundResult.getStageResultList()) {
                for (ElementalBondsBlock elementalBondsBlock : elementalBondsOperateStageResult.getEliminateBlockList()) {
                    boolean isSkill22Block = false;
                    for (ElementalBondsBlockEffect elementalBondsBlockEffect : elementalBondsBlock.getElementalBondsBlockEffectList()) {
                        if (elementalBondsBlockEffect.getEffectType() == ElementalBondsBlockEffectType.SKILL_22 && elementalBondsBlockEffect.getTimes() < 1) {
                            isSkill22Block = true;
                            break;
                        }
                    }
                    if (isSkill22Block) {
                        useElementalBondsBlockList.add(elementalBondsBlock);
                    }
                }
            }
        }
        if (useElementalBondsBlockList.isEmpty()) {
            return;
        }

        // 找可以补位的位置
        List<ElementalBondsBlock> allElementalBondsBlockList = new ArrayList<>();
        for (List<ElementalBondsBlock> elementalBondsBlockList : elementalBondsGameData.getBlockList()) {
            for (ElementalBondsBlock elementalBondsBlock : elementalBondsBlockList) {
                if (elementalBondsBlock.getElementalBondsBlockType().getBigType() == ElementalBondsBlockBigType.NORMAL) {
                    boolean isSkill22Block = false;
                    for (ElementalBondsBlockEffect elementalBondsBlockEffect : elementalBondsBlock.getElementalBondsBlockEffectList()) {
                        if (elementalBondsBlockEffect.getEffectType() == ElementalBondsBlockEffectType.SKILL_22) {
                            isSkill22Block = true;
                            break;
                        }
                    }
                    if (!isSkill22Block) {
                        allElementalBondsBlockList.add(elementalBondsBlock);
                    }
                }
            }
        }

        // 打乱
        Collections.shuffle(allElementalBondsBlockList, random);

        // 随机飞过去
        ElementalBondsOperateEffect elementalBondsOperateEffect = new ElementalBondsOperateEffect(ElementalBondsEffectType.DEMON_FLY);
        for (int i = 0; i < useElementalBondsBlockList.size() && i < allElementalBondsBlockList.size(); i++) {
            ElementalBondsBlockEffect elementalBondsBlockEffect = new ElementalBondsBlockEffect(ElementalBondsBlockEffectType.SKILL_22);
            elementalBondsBlockEffect.setEffectValue(random.nextInt(3) + 1); // 1、2、3对应Y、X、十字
            elementalBondsBlockEffect.setTimes(1);
            ElementalBondsBlock elementalBondsBlock = allElementalBondsBlockList.get(i);
            elementalBondsBlock.addElementalBondsBlockEffect(elementalBondsBlockEffect);

            elementalBondsOperateEffect.addElementalBondsBlock(useElementalBondsBlockList.get(i));
            elementalBondsOperateEffect.addElementalBondsBlock(elementalBondsBlock);
        }

        // 添加结果
        elementalBondsOperateResult.addElementalBondsOperateEffect(elementalBondsOperateEffect);
    }

    public static void card_23_moveEnd(ElementalBondsGameData elementalBondsGameData, ElementalBondsOperateResult elementalBondsOperateResult,
                                       ElementalBondsOperateType elementalBondsOperateType, Random random) {
        // 移动和使用卡片时才触发
        if (elementalBondsOperateType != ElementalBondsOperateType.MOVE && elementalBondsOperateType != ElementalBondsOperateType.USE_CARD) {
            return;
        }

        ElementalBondsCardType elementalBondsCardType = ElementalBondsCardType.CARD_23;
        ElementalBondsCardConfig elementalBondsCardConfig = ElementalBondsConfigMgr.getInstance().getCardConfigMap().get(elementalBondsCardType.getType());
        // 只要存在机巧盒，就可以丢出炸弹
        ElementalBondsBlock smartBoxBlock = ElementalBondsBlockLogic.getSmartBoxBlock(elementalBondsGameData.getBlockList());
        if (smartBoxBlock == null) {
            return;
        }
        // 3.扔出炸弹
        // 获取可选方块
        List<ElementalBondsBlock> randomElementalBondsBlockList = new ArrayList<>();
        for (List<ElementalBondsBlock> elementalBondsBlockList : elementalBondsGameData.getBlockList()) {
            for (ElementalBondsBlock elementalBondsBlock : elementalBondsBlockList) {
                if (elementalBondsBlock.getElementalBondsBlockType().getBigType() == ElementalBondsBlockBigType.NORMAL) {
                    randomElementalBondsBlockList.add(elementalBondsBlock);
                }
            }
        }
        // 打乱
        Collections.shuffle(randomElementalBondsBlockList, random);
        // 取方块变机巧盒炸弹
        List<ElementalBondsBlock> chooseElementalBondsBlockList = new ArrayList<>();
        // 第一个格子是机巧盒
        chooseElementalBondsBlockList.add(smartBoxBlock);
        for (int i = 0; i < elementalBondsCardConfig.getCardParamList().get(1) && i < randomElementalBondsBlockList.size(); i++) {
            ElementalBondsBlock elementalBondsBlock = randomElementalBondsBlockList.get(i);
            elementalBondsBlock.setElementalBondsBlockType(ElementalBondsBlockType.SMART_BOX_LANDMINE);
            chooseElementalBondsBlockList.add(elementalBondsBlock);
        }

        //添加效果
        elementalBondsOperateResult.addElementalBondsOperateEffect(new ElementalBondsOperateEffect(elementalBondsCardType, 3, chooseElementalBondsBlockList));
        // 技能结束
        elementalBondsOperateResult.addElementalBondsOperateEffect(new ElementalBondsOperateEffect(elementalBondsCardType, 0));
    }

}
